package yxy.game.pm2.module.avatar;

import org.redisson.api.RMap;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.avatar;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.Sign;
import yxy.game.pm2.bean.currency.CurrencyType;
import yxy.game.pm2.bean.db.newDao.AvatarDAO;
import yxy.game.pm2.bean.db.po.AvatarPo;
import yxy.game.pm2.bean.module.BaseGameRedisLockBean;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.module.CurrencyHandle;
import yxy.game.pm2.module.tip.TipHandle;
import yxy.game.pm2.module.tip.TipType;

import java.util.*;

import static yxy.apple.util.StringTrans.booleanArray2String;
import static yxy.apple.util.StringTrans.string2BooleanArray;

public class AvatarModule extends BaseGameRedisLockBean {

	static protected enum AvatarCheckType {
		武将星级, 玩家等级,;

		static protected AvatarCheckType forNumber(int value) {
			switch (value) {
			case 1:
				return 武将星级;
			case 2:
				return 玩家等级;
			default:
				return null;
			}
		}
	}

	// bean===========================================================================
	private String dataCode;
	private boolean newfound;
	private boolean[] conditions = new boolean[2];

	public String getDataCode() {
		return dataCode;
	}

	public void setDataCode(String dataCode) {
		this.dataCode = dataCode;
	}

	public boolean[] getConditions() {
		return conditions;
	}

	public void setConditions(boolean[] conditions) {
		this.conditions = conditions;
	}

	public boolean isNewfound() {
		return newfound;
	}

	public void setNewfound(boolean newfound) {
		this.newfound = newfound;
	}
	// func==========================================================================

	private boolean ok() {
		boolean ok = true;
		for (int i = 0; i < conditions.length; i++) {
			ok &= conditions[i];
		}
		return ok;
	}

	static public void check(String playerCode, AvatarCheckType type, int... params) {
		Map<String, avatar> datas = DataCenter.getAllData(avatar.class);
		Set<String> allavatar = Sign.all(playerCode, CurrencyType.CT_形象);
		String lockKey = lockKey(playerCode);
		try {
			if (tryLock(lockKey)) {
				for (avatar data : datas.values()) {
					if (allavatar.contains(data.getCode())) {
						continue;// 已经有这个形象了
					}
					AvatarModule module = get(playerCode, data.getCode());
					if (module == null) {
						module = new AvatarModule();
						module.setDataCode(data.getCode());
					}
					if (module.isNewfound()) {
						continue;
					}
					boolean[] conditions = module.getConditions();
					boolean update = false;
					for (int i = 0; i < data.getConditiontype().length; i++) {
						AvatarCheckType checkType = AvatarCheckType.forNumber(data.getConditiontype()[i]);
						if (!checkType.equals(type)) {
							continue;
						}
						switch (checkType) {
						case 武将星级:
							if (params[0] == data.getId() && params[1] >= data.getConditionnum()[i]) {
								conditions[i] = true;
								update |= true;
							}
							break;
						case 玩家等级:
							if (params[0] >= data.getConditionnum()[i]) {
								conditions[i] = true;
								update |= true;
							}
							break;
						default:
							update |= false;
							continue;
						}
					}
					if (!update) {
						continue;
					}
					if (module.ok()) {
						new CurrencyHandle().addCurrency(playerCode, CCReason.角色形象, Currency.create(CurrencyType.CT_形象, data.getId(), 1));

						module.setNewfound(true);
						new TipHandle().updateTip(playerCode, TipType.主公_形象切页, true);
					}

					set(playerCode, module);
				}
			}
		} catch (Exception e) {
		} finally {
			unlock(lockKey);
		}

	}

	static public Collection<Integer> newfound(String playerCode) {
		ArrayList<Integer> list = new ArrayList<>();

		try {
			Collection<AvatarModule> all = touch(playerCode).readAllValues();
			for (AvatarModule module : all) {
				if (module.isNewfound()) {
					list.add(Integer.parseInt(module.getDataCode()));
					remove(playerCode, module.getDataCode());
				}
			}

			new TipHandle().updateTip(playerCode, TipType.主公_形象切页, false);
		} catch (Exception e) {
		}

		return list;
	}

	// redis==========================================================================

	static public String key(String playerCode) {
		return String.format("PLAYER:%s:MODULE:AVATAR", playerCode);
	}

	static private RMap<String, AvatarModule> touch(String playerCode) {
		RMap<String, AvatarModule> touch = null;
			touch = redis().client().getMap(key(playerCode));
			if(touch == null){
				List<AvatarPo> avatarPos = AvatarDAO.getList(playerCode);

				if(avatarPos != null && avatarPos.size()>0){
					for(int i = 0; i < avatarPos.size(); i++){
						AvatarModule avatarModule = new AvatarModule();
						avatarModule.setDataCode(avatarPos.get(i).getDataCode());
						avatarModule.setNewfound(avatarPos.get(i).isNewFound());
						String conditionsStr = avatarPos.get(i).getConditions();
						avatarModule.setConditions(string2BooleanArray(conditionsStr));

						touch.put(avatarPos.get(i).getDataCode(), avatarModule);
					}
				}
			}
		return touch;
	}

	static private AvatarModule get(String playerCode, String code) {
		try {
			AvatarModule module = touch(playerCode).get(code);
			return module;
		} catch (Exception e) {
			return null;
		}
	}

	static private void remove(String playerCode, String avatarCode) {
			touch(playerCode).remove(avatarCode);
	}

	static private AvatarModule set(String playerCode, AvatarModule module) {
		touch(playerCode).put(module.getDataCode(), module);
		return module;
	}

	//数据归档到数据库
	public static void saveToDB(String playerCode) {
		try {
			//存储
			List<AvatarPo> avatarPos = new ArrayList<>();
			RMap<String, AvatarModule> touch = redis().client().getMap(key(playerCode));
			if (touch.isExists()) {
				for (Map.Entry<String, AvatarModule> entry : touch.readAllEntrySet()) {
					AvatarModule value = entry.getValue();
					AvatarPo avatarPo = new AvatarPo();
					avatarPo.setPlayerCode(playerCode);
					avatarPo.setDataCode(value.getDataCode());
					avatarPo.setNewFound(value.isNewfound());
					avatarPo.setConditions(booleanArray2String(value.getConditions()));
					avatarPos.add(avatarPo);

					AvatarDAO.replace(avatarPos);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	//从redis移走数据
	public static void removeAllFromRedis(String playerCode) {
		try {
			touchBucket(key(playerCode)).delete();
		} catch (RedisException e) {
			e.printStackTrace();
		}
	}

	// lock==========================================================================

	static private String lockKey(String playerCode) {
		return String.format("lock:%s", key(playerCode));
	}

}
